const express = require('express');
const cors = require('cors');
const http = require('http');
const { Server } = require('socket.io');
require('dotenv').config();

const authRoutes = require('./routes/auth');
const friendsRoutes = require('./routes/friends');
const chatRoutes = require('./routes/chat');
const postsRoutes = require('./routes/posts');
const driftBottlesRoutes = require('./routes/driftBottles');
const { testConnection } = require('./config/database');

const app = express();
const server = http.createServer(app);
const io = new Server(server, {
  cors: {
    origin: "*",
    methods: ["GET", "POST"]
  }
});
const PORT = process.env.PORT || 3000;

// 中间件
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// WebSocket 认证中间件
const jwt = require('jsonwebtoken');
const Chat = require('./models/Chat');

// Socket.IO 连接处理
io.use((socket, next) => {
  const token = socket.handshake.auth.token;
  if (!token) {
    return next(new Error('认证失败：缺少token'));
  }
  
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    // JWT中使用sub字段作为用户ID
    socket.userId = decoded.sub;
    socket.userInfo = {
      userId: decoded.sub,
      email: decoded.email,
      ...decoded
    };
    next();
  } catch (error) {
    next(new Error('认证失败：无效token'));
  }
});

// WebSocket 聊天功能
io.on('connection', (socket) => {
  console.log(`[${new Date().toISOString()}] 用户连接WebSocket:`, {
    userId: socket.userId,
    socketId: socket.id
  });
  
  // 用户加入自己的房间（用于接收消息）
  socket.join(`user_${socket.userId}`);
  
  // 加入会话房间
  socket.on('join_conversation', async (data) => {
    try {
      // 检查data是否存在
      if (!data || typeof data !== 'object') {
        return socket.emit('error', {
          message: '无效的数据格式'
        });
      }
      
      const { conversationId } = data;
      
      // 严格的参数验证
      if (conversationId === undefined || conversationId === null) {
        return socket.emit('error', {
          message: '会话ID不能为空'
        });
      }
      
      // 确保参数类型正确
      const validConversationId = parseInt(conversationId);
      if (isNaN(validConversationId)) {
        return socket.emit('error', {
          message: '无效的会话ID格式'
        });
      }
      
      const validUserId = socket.userId;
      if (!validUserId) {
        return socket.emit('error', {
          message: '用户身份验证失败'
        });
      }
      
      // 验证用户是否有权限加入该会话
      const conversation = await Chat.getConversationDetail(validConversationId, validUserId);
      
      socket.join(`conversation_${validConversationId}`);
      socket.currentConversation = validConversationId;
      
      socket.emit('joined_conversation', {
        success: true,
        conversationId: validConversationId,
        message: '成功加入会话'
      });
      
      console.log(`[${new Date().toISOString()}] 用户加入会话:`, {
        userId: validUserId,
        conversationId: validConversationId
      });
    } catch (error) {
      console.error('加入会话失败:', error);
      socket.emit('error', {
        message: error.message || '加入会话失败'
      });
    }
  });
  
  // 发送消息
  socket.on('send_message', async (data) => {
    try {
      // 检查data是否存在
      if (!data || typeof data !== 'object') {
        return socket.emit('error', {
          message: '无效的消息数据格式'
        });
      }
      
      const { conversationId, content } = data;
      
      // 严格的参数验证
      if (conversationId === undefined || conversationId === null) {
        return socket.emit('error', {
          message: '会话ID不能为空'
        });
      }
      
      if (!content || typeof content !== 'string' || content.trim().length === 0) {
        return socket.emit('error', {
          message: '消息内容不能为空'
        });
      }
      
      if (content.length > 1000) {
        return socket.emit('error', {
          message: '消息内容不能超过1000个字符'
        });
      }
      
      // 确保参数类型正确
      const validConversationId = parseInt(conversationId);
      if (isNaN(validConversationId)) {
        return socket.emit('error', {
          message: '无效的会话ID格式'
        });
      }
      
      const validContent = content.trim();
      const validUserId = socket.userId;
      
      if (!validUserId) {
        return socket.emit('error', {
          message: '用户身份验证失败'
        });
      }
      
      // 发送消息到数据库
      const message = await Chat.sendMessage(validConversationId, validUserId, validContent);
      
      // 获取发送者信息
      const messageWithSender = {
        ...message,
        senderNickName: socket.userInfo.nickName || '未知用户',
        senderAvatar: socket.userInfo.avatar || null
      };
      
      // 向会话中的所有用户广播消息
      io.to(`conversation_${validConversationId}`).emit('new_message', messageWithSender);
      
      console.log(`[${new Date().toISOString()}] WebSocket消息广播:`, {
        userId: validUserId,
        conversationId: validConversationId,
        messageId: message.id,
        roomName: `conversation_${validConversationId}`,
        broadcastData: messageWithSender
      });
      
      console.log(`[${new Date().toISOString()}] WebSocket消息发送:`, {
        userId: validUserId,
        conversationId: validConversationId,
        messageId: message.id
      });
    } catch (error) {
      console.error('发送消息失败:', error);
      socket.emit('error', {
        message: error.message || '发送消息失败'
      });
    }
  });
  
  // 离开会话房间
  socket.on('leave_conversation', (data) => {
    const { conversationId } = data;
    socket.leave(`conversation_${conversationId}`);
    socket.currentConversation = null;
    
    socket.emit('left_conversation', {
      success: true,
      conversationId,
      message: '已离开会话'
    });
  });
  
  // 用户断开连接
  socket.on('disconnect', () => {
    console.log(`[${new Date().toISOString()}] 用户断开WebSocket连接:`, {
      userId: socket.userId,
      socketId: socket.id
    });
  });
});

// 路由
app.use('/auth', authRoutes);
app.use('/friends', friendsRoutes);
app.use('/chat', chatRoutes);
app.use('/posts', postsRoutes);
app.use('/drift-bottles', driftBottlesRoutes);

// 根路由
app.get('/', (req, res) => {
  res.json({
    code: 200,
    message: 'Express API Server is running',
    data: {
      version: '1.0.0',
      endpoints: {
        auth: {
          login: 'POST /auth/login'
        },
        friends: {
          list: 'GET /friends',
          search: 'GET /friends/search?email=xxx',
          add: 'POST /friends',
          remove: 'DELETE /friends',
          sendRequest: 'POST /friends/request',
          getRequests: 'GET /friends/requests',
          handleRequest: 'PUT /friends/requests/:requestId'
        },
        chat: {
          conversations: 'GET /chat/conversations',
          createConversation: 'POST /chat/conversations',
          conversationDetail: 'GET /chat/conversations/:id',
          sendMessage: 'POST /chat/conversations/:id/messages',
          getMessages: 'GET /chat/conversations/:id/messages',
          deleteConversation: 'DELETE /chat/conversations/:id',
          websocket: 'WebSocket /socket.io (需要JWT认证)'
        },
        posts: {
          create: 'POST /posts',
          friendsPosts: 'GET /posts/friends',
          userPosts: 'GET /posts/user/:userId',
          detail: 'GET /posts/:postId',
          delete: 'DELETE /posts/:postId',
          like: 'POST /posts/:postId/like',
          likes: 'GET /posts/:postId/likes',
          comment: 'POST /posts/:postId/comments',
          comments: 'GET /posts/:postId/comments',
          replies: 'GET /posts/comments/:commentId/replies',
          deleteComment: 'DELETE /posts/comments/:commentId'
        },
        driftBottles: {
          throw: 'POST /drift-bottles',
          pick: 'POST /drift-bottles/pick',
          mySent: 'GET /drift-bottles/my-sent',
          myPicked: 'GET /drift-bottles/my-picked'
        }
      }
    }
  });
});

// 404 处理
app.use('*', (req, res) => {
  res.status(404).json({
    code: 404,
    message: '接口不存在',
    data: null
  });
});

// 错误处理中间件
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({
    code: 500,
    message: '服务器内部错误',
    data: null
  });
});

server.listen(PORT, async () => {
  console.log(`Server is running on http://localhost:${PORT}`);
  console.log(`WebSocket server is running on ws://localhost:${PORT}`);
  
  // 测试数据库连接
  await testConnection();
});

module.exports = { app, server, io };